﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using Labthink.PCSoft.UniversalHost4.DataAccess;
using Labthink.PCSoft.UniversalHost4.Instrument.Model;
using Labthink.PCSoft.UniversalHost4.Instrument.ViewModel;
using Labthink.PCSoft.UniversalHost4.Model;
using Labthink.PCSoft.UniversalHost4.Model.Setting;
using Labthink.PCSoft.UniversalHost4.UserControls;
using Labthink.PCSoft.UniversalHost4.Utility;
using NLog;
using SystemSettings;

namespace Labthink.PCSoft.UniversalHost4.Instrument.Forms
{
    public partial class FrmParamSet
    {
        public bool SetOrCancel { get; set; }
        private List<ParamTraceReason> _ptrs;
        private NotifyManager _notify;
        private bool _hasLoaded;
        private TestType1 _dp = new TestType1();
        private Logger Log = LogManager.GetCurrentClassLogger();

        public FrmParamSet()
        {
            InitializeComponent();
            if (!Debugger.IsAttached)
            {
                WindowState = WindowState.Maximized;
            }
            else
            {
                WindowState = WindowState.Normal;

                double height = SystemParameters.FullPrimaryScreenHeight;
                double width = SystemParameters.FullPrimaryScreenWidth;

                Width = 1024;
                Height = 768;

                Top = (height - Height) / 2;
                Left = (width - Width) / 2;
            }

            SerialPortHelper.OnTestStatusChangedHandler += OnTestStatusChangedHandler;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (DesignerProperties.GetIsInDesignMode(this))
            {
                return;
            }

            _notify = NotifyManager.InstanceManager(this);
            IntPtr a = new WindowInteropHelper(this).Handle;
            int temp = Win32Api.GetWindowLong(a, -20);
            Win32Api.SetWindowLong(a, -20, temp | 0x08000000);
            var hwndSource = HwndSource.FromHwnd(a);
            hwndSource?.AddHook(WndProc);

            Loading.Visibility = Visibility.Visible;

            TxtOpName.Value = Common.CurrentUser.UserName;
            _loadAll();
        }

        private void OnTestStatusChangedHandler(object sender, ComTestStatusEventArgs e)
        {
            Dispatcher?.Invoke(() =>
            {
                if (e.Status == TestStatus.FullySaved)
                {
                    // 保存完成后变为Idle状态
                }
            });
        }

        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {

        }

        private void BtnBack_OnClick(object sender, RoutedEventArgs e)
        {
            Hide();
        }

        /// <summary>
        /// 重置参数 (取消上次设置后的修改）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnResetParam_Click(object sender, RoutedEventArgs e)
        {
            SetOrCancel = false;
            _loadData();
            Hide();
        }

        /// <summary>
        /// 设置参数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnSetParam_Click(object sender, RoutedEventArgs e)
        {
            // 读取输入数据
            GetInput();

            Loading.Visibility = Visibility.Visible;

            //记录参数变化
            if (!_createParamChanged(_dp))
            {
                Loading.Visibility = Visibility.Collapsed;
                return;
            }

            //设置参数
            var strTime = DateTime.Now;

            //记录参数变化
            if (_ptrs != null)
            {
                _trace(_ptrs);
                _ptrs = null;
            }

            Log.Debug("用户点击【设置参数】按钮");
            UpdateParamXml();
            Loading.Visibility = Visibility.Collapsed;

            Hide();
        }

        /// <summary>
        ///更新到当前方案
        /// </summary>
        private void UpdateParamXml()
        {
            List<Param> ps = Common.CurrentParam.Params;
            ps.Get(10069).Value = _dp.TestName.Value;
            ps.Get(10070).Value = _dp.SpecimenName.Value;
            ps.Get(10071).Value = _dp.SpecimenMaterial.Value;
            ps.Get(10072).Value = _dp.SpecimenId.Value;
            ps.Get(10076).Value = _dp.Temperature.Value;
            ps.Get(10077).Value = _dp.Humidity.Value;
            ps.Get(10078).Value = _dp.Standard.Value;
            ps.Get(10079).Value = _dp.InspOrga.Value;
            ps.Get(10080).Value = _dp.Manufacturer.Value;
            ps.Get(10081).Value = _dp.SpecimenBatch.Value;

            Common.CurrentParam.LastUsed = DateTime.Now;
            XmlHelper.SaveToXml(Common.CurrentParam, Common.CurrentParam.Filename);
        }

        private void _loadAll()
        {
            ShowInTaskbar = false;

            //_initData();
            _loadData();
            Loading.Visibility = Visibility.Collapsed;
            if (Common.BaseInfo.Gmp)
            {
                List<ParamForTrace> pts = RoleAndPerRepository.GetTracedParams();
                foreach (ParamForTrace pt in pts)
                {
                    CurrentRepository.PackParamForTrace(pt);
                }

                Common.ParamForTraces = pts;
            }

            if (!_hasLoaded)
            {
                LoadPer();
                _hasLoaded = true;
            }
        }

        private void LoadPer()
        {
            if (Common.Permissions.All(p => p.Code != "ParamSet".Clear()))
            {
                BtnSetParam.Visibility = Visibility.Collapsed;
            }
        }

        public void ReConfigPermission()
        {
            LoadPer();
            TxtOpName.Value = Common.CurrentUser.UserName;
        }

        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == 0x0216)
            {
                System.Drawing.Rectangle rect = (System.Drawing.Rectangle)Marshal.PtrToStructure(lParam, typeof(System.Drawing.Rectangle));
                Left = rect.Left;
                Top = rect.Top;
            }

            return IntPtr.Zero;
        }

        private void _loadData()
        {
            var currentParam = Common.CurrentParam;
            //if (currentParam.TestType == 1)
            {
                _dp.FillFrom(currentParam.Params);

                TxtTestName.Label = _dp.TestName.Text;
                TxtTestName.Value = _dp.TestName.Value + "";
                TxtTestName.MaxLength = _dp.TestName.MaxLength;

                TxtSpecimenName.Label = _dp.SpecimenName.Text;
                TxtSpecimenName.Value = _dp.SpecimenName.Value + "";
                TxtSpecimenName.MaxLength = _dp.SpecimenName.MaxLength;

                TxtSpecimenId.Label = _dp.SpecimenId.Text;
                TxtSpecimenId.Value = _dp.SpecimenId.Value + "";
                TxtSpecimenId.MaxLength = _dp.SpecimenId.MaxLength;

                TxtSpecimenMaterial.Label = _dp.SpecimenMaterial.Text;
                TxtSpecimenMaterial.Value = _dp.SpecimenMaterial.Value + "";
                TxtSpecimenMaterial.MaxLength = _dp.SpecimenMaterial.MaxLength;

                TxtManufacturer.Label = _dp.Manufacturer.Text;
                TxtManufacturer.Value = _dp.Manufacturer.Value + "";
                TxtManufacturer.MaxLength = _dp.Manufacturer.MaxLength;

                TxtBatch.Label = _dp.SpecimenBatch.Text;
                TxtBatch.Value = _dp.SpecimenBatch.Value + "";
                TxtBatch.MaxLength = _dp.SpecimenBatch.MaxLength;

                TxtLabTemp.Label = $"{_dp.Temperature.Text}"; //({_dp.Temperature.Unit})
                TxtLabTemp.Value = _dp.Temperature.Value + "";
                TxtLabTemp.MaxValue = _dp.Temperature.Max;
                TxtLabTemp.MinValue = _dp.Temperature.Min;

                TxtLabHum.Label = $"{_dp.Humidity.Text}"; //({_dp.Humidity.Unit})
                TxtLabHum.Value = _dp.Humidity.Value + "";
                TxtLabHum.MaxValue = _dp.Humidity.Max;
                TxtLabHum.MinValue = _dp.Humidity.Min;

                TxtStandard.Label = _dp.Standard.Text;
                TxtStandard.Value = _dp.Standard.Value + "";
                TxtStandard.MaxLength = _dp.Standard.MaxLength;

                TxtInspOrga.Label = _dp.InspOrga.Text;
                TxtInspOrga.Value = _dp.InspOrga.Value + "";
                TxtInspOrga.MaxLength = _dp.InspOrga.MaxLength;

                TxtOpName.Label = _dp.OpName.Text;
            }

            TxtOpName.Value = Common.CurrentUser.UserName;

            var s = from language in Common.LanguagesFromDb.Where(l =>
                    l.LanguageId.StartsWith("TestMethod") && l.LanguageId.Replace("TestMethod", "") != "")
                    select new TextAndValue
                    {
                        Text = language.Text,
                        Value = language.LanguageId.Replace("TestMethod", "")
                    };
        }

        private void GetInput()
        {
            _dp.TestName.Value = TxtTestName.Value;
            _dp.SpecimenName.Value = TxtSpecimenName.Value;
            _dp.SpecimenId.Value = TxtSpecimenId.Value;
            _dp.SpecimenMaterial.Value = TxtSpecimenMaterial.Value;
            _dp.Manufacturer.Value = TxtManufacturer.Value;
            _dp.SpecimenBatch.Value = TxtBatch.Value;
            _dp.Standard.Value = TxtStandard.Value;
            _dp.InspOrga.Value = TxtInspOrga.Value;
            _dp.Humidity.Value = TxtLabHum.Value;
            _dp.Temperature.Value = TxtLabTemp.Value;
            _dp.OpName.Value = Common.CurrentUser.UserName;
        }

        private void _trace(List<ParamTraceReason> ptrs)
        {
            foreach (var ptr in ptrs)
            {
                string log;
                if (ptr.ColName == "CupStatus")
                {
                    log = string.Format(LanguageManager.GetLanguageValue("ReasonForCupStatus" + ptr.NewValue), ptr.CupNo, ptr.Reason);
                }
                else
                {
                    if (ptr.ColName == "TestMode")
                    {
                        ptr.OldValue = LanguageManager.GetLanguageValue("TestMode" + ptr.OldValue);
                        ptr.NewValue = LanguageManager.GetLanguageValue("TestMode" + ptr.NewValue);
                    }
                    if (ptr.ColName == "TestMethod")
                    {
                        ptr.OldValue = LanguageManager.GetLanguageValue("TestMethod" + ptr.OldValue);
                        ptr.NewValue = LanguageManager.GetLanguageValue("TestMethod" + ptr.NewValue);
                    }

                    //var log = string.Format("参数 {0} 的值被修改，原值：{1}，修改为：{2}，修改原因：{3}", ptr.Name, ptr.OldValue, ptr.NewValue,
                    //    ptr.Reason);
                    log = string.Format(ptr.CupNo > 0 ? LanguageManager.GetLanguageValue("ReasonForChangedLogCup") : LanguageManager.GetLanguageValue("ReasonForChangedLog"), ptr.Name, ptr.OldValue, ptr.NewValue, ptr.Reason);
                }

                var ol = new OperateLog
                {
                    LogTime = DateTime.Now,
                    Content = log,
                    OpType = "Trace"
                };

                LogRepository.AddLog(ol);
            }
        }

        private void FrmParamSet_OnClosing(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
            Visibility = Visibility.Hidden;
        }

        private bool _createParamChanged(BaseParam dp)
        {
            //if (Common.BaseInfo.Gmp)
            //{
            //    //开启GMP功能，追踪参数变化
            //    _ptrs = CupManager.GetChangedReason(Common.CurrentParamProject.DefaultParam, dp, Common.CurrentParamProject.CupParams, cps, Common.ParamForTraces);
            //    if (_ptrs.Count > 0)
            //    {
            //        foreach (var ptr in _ptrs.Where(p => p.ColName == "CupStatus"))
            //        {
            //            ptr.Name = string.Format(Resources.GetLanguageValue("CupStatus" + ptr.NewValue), ptr.CupNo);
            //        }

            //        foreach (var ptr in _ptrs.Where(p => p.ColName != "CupStatus" && p.CupNo > 0))
            //        {
            //            ptr.Name = Resources.GetLanguageValue("Cup" + ptr.CupNo) + " " + ptr.Name;
            //        }

            //        var res = new FrmParamForTrace
            //        {
            //            Ptrs = _ptrs
            //        };

            //        var re = res.ShowDialog(Application.Current.MainWindow);
            //        if (!re.HasValue || !re.Value)
            //        {
            //            return false;
            //        }
            //        _ptrs = res.Ptrs;
            //        return true;
            //    }
            //}
            return true;
        }
    }
}